package main

import (
	"bufio"
	"bytes"
	"crypto/rand"
	"crypto/rsa"
	"crypto/tls"
	"crypto/x509"
	"crypto/x509/pkix"
	"database/sql"
	"embed"
	"encoding/json"
	"encoding/pem"
	"fmt"
	"html/template"
	"io"
	"io/fs"
	"log"
	"math/big"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/c-bata/go-prompt"
	"github.com/gorilla/websocket"
	"golang.org/x/sys/windows"
	"gopkg.in/yaml.v3"

	_ "github.com/lib/pq"
)

//go:embed templates/*
var embeddedTemplates embed.FS

// Version will be injected at build time using -ldflags
var Version = "dev"

var commands = []string{
	"help",
	"migen",
	"migrun",
	"mig-crack-license",
	"mig-init-db",
	"mig-check-env",
}

var lastCmd string

const (
	greenCheck = "\033[32m✓\033[0m"
	redCross   = "\033[31m\033[0m"
	redText    = "\033[31m%s\033[0m"

	// Database connection constants
	dbHost    = "127.0.0.1"
	dbPort    = 65433
	dbUser    = "pgsqladmin"
	dbName    = "rda"
	dbSSLMode = "disable"
)

func printSuccess(msg string) {
	fmt.Printf("%s %s\n", greenCheck, msg)
}

func printError(msg string) {
	fmt.Printf("%s %s\n", redCross, fmt.Sprintf(redText, msg))
}

func completer(d prompt.Document) []prompt.Suggest {
	return nil
}

func executor(cmd string) {
	lastCmd = cmd
	cmd = strings.TrimSpace(cmd)
	switch cmd {
	case "help":
		fmt.Println("Available commands:")
		fmt.Println("  help               - Show this help message")
		fmt.Println("  migen              - 收集迁移插件配置，生成插件项目，包含前端、后端项目")
		fmt.Println("  migrun             - 启动调试RDA环境")
		fmt.Println("  mig-crack-license  - 延长RDA License时间")
		fmt.Println("  mig-init-db        - 执行数据库脚本到插件对应的schema中")
		fmt.Println("  mig-check-env      - Check development environment requirements")
		fmt.Println(`
命令使用指引:
	1. 首先执行mig-check-env命令，检查开发环境是否满足要求
	2. 使用mig-crack-license延长RDA License时间
	3. 然后使用migen命令，生成插件配置，输入插件的名称、在RDA中的code、插件后端运行的端口等信息，插件会生成配置文件，后续做其他操作会重新加载该配置，然后生成插件项目代码
	4. 使用migrun命令启动调试环境，该命令会收集插件后端调试的端口，插件前端的调试端口，以及meta.json，然后随机启动一个端口，后续访问RDA进行插件联合集成调试，访问该端口，即可在不按照插件的情况下在RDA中访问插件的页面
		`)
	case "mig-check-env":
		checkEnvironment()
	case "migen":
		if err := handleMigGen(); err != nil {
			printError(fmt.Sprintf("生成失败: %v", err))
		}
	case "migrun":
		if err := handleMigRun(); err != nil {
			printError(fmt.Sprintf("运行失败: %v", err))
		}
	case "mig-init-db":
		if err := handleMigInitDb(); err != nil {
			printError(fmt.Sprintf("初始化数据库失败: %v", err))
		} else {
			printSuccess("数据库已成功初始化")
		}
	case "mig-crack-license":
		if err := handleLicenseCrack(); err != nil {
			printError(fmt.Sprintf("License破解失败: %v", err))
		} else {
			printSuccess("License已成功延长至2036年")
		}
	case "":
		// Do nothing for empty input
	default:
		fmt.Printf("Unknown command: %s\n", cmd)
		fmt.Println("Type 'help' to see available commands")
	}
}

func handleMigInitDb() error {
	// 1. 选择迁移插件配置
	config, err := selectMigratorConfig()
	if err != nil {
		return fmt.Errorf("选择迁移插件配置失败: %v", err)
	}

	// 2. 提示用户录入SQL目录
	reader := bufio.NewReader(os.Stdin)
	fmt.Print("\n请输入SQL文件所在的目录路径: ")
	sqlDir, err := reader.ReadString('\n')
	sqlDir = strings.TrimSpace(sqlDir)

	// 检查目录是否存在
	if !fileExists(sqlDir) {
		return fmt.Errorf("目录不存在: %s", sqlDir)
	}

	// 查找.sql文件
	sqlFiles, err := findSqlFiles(sqlDir)
	if err != nil {
		return fmt.Errorf("查找SQL文件失败: %v", err)
	}

	if len(sqlFiles) == 0 {
		return fmt.Errorf("在目录 %s 中未找到.sql文件", sqlDir)
	}

	fmt.Printf("\n找到以下SQL文件:\n")
	for i, file := range sqlFiles {
		fmt.Printf("[%d] %s\n", i+1, file)
	}

	// 4. 依次执行SQL文件
	fmt.Printf("\n开始执行SQL文件...\n")

	db, err := connectToDatabase(config.Code, config.DBPassword)
	if err != nil {
		return err
	}
	defer db.Close()
	for _, file := range sqlFiles {
		fmt.Printf("\n执行文件: %s\n", file)

		// 读取SQL文件内容
		content, err := os.ReadFile(filepath.Join(sqlDir, file))
		if err != nil {
			return fmt.Errorf("读取SQL文件失败 %s: %v", file, err)
		}

		// 执行SQL
		if _, err := db.Exec(string(content)); err != nil {
			return fmt.Errorf("执行SQL文件失败 %s: %v", file, err)
		}

		fmt.Printf("%s SQL文件执行成功: %s\n", greenCheck, file)
	}

	return nil
}

func findSqlFiles(dir string) ([]string, error) {
	files, err := os.ReadDir(dir)
	if err != nil {
		return nil, err
	}

	var sqlFiles []string
	for _, file := range files {
		if !file.IsDir() && strings.HasSuffix(strings.ToLower(file.Name()), ".sql") {
			sqlFiles = append(sqlFiles, file.Name())
		}
	}

	return sqlFiles, nil
}

func isAdmin() (bool, error) {
	var sid *windows.SID

	// 尝试获取 Administrator 组的 SID
	err := windows.AllocateAndInitializeSid(
		&windows.SECURITY_NT_AUTHORITY,
		2,
		windows.SECURITY_BUILTIN_DOMAIN_RID,
		windows.DOMAIN_ALIAS_RID_ADMINS,
		0, 0, 0, 0, 0, 0,
		&sid)
	if err != nil {
		return false, fmt.Errorf("SID allocation error: %v", err)
	}
	defer windows.FreeSid(sid)

	// 检查当前进程是否在 Administrator 组中
	token := windows.Token(0)
	member, err := token.IsMember(sid)
	if err != nil {
		return false, fmt.Errorf("token membership error: %v", err)
	}

	return member, nil
}

func printWelcome() {
	fmt.Println("----------------------------------------------------------------")
	fmt.Printf("Welcome to RDA %s terminal\n", Version)
	fmt.Println("Powered by RDA Team(PIC: tangfa 30031666)")
	fmt.Println("\nPlease start journey for the RDA Terminal with help command")
	fmt.Println("----------------------------------------------------------------")
}

func checkEnvironment() {
	// 检查 JDK 版本
	cmd := exec.Command("java", "-version")
	output, err := cmd.CombinedOutput()
	if err != nil {
		printError("检查JDK失败")
		fmt.Printf("错误: %v\n", err)
		fmt.Println("输出:", string(output))
		return
	}
	outputStr := strings.ToLower(string(output))
	if !strings.Contains(outputStr, "version \"17") {
		printError("JDK版本不正确")
		fmt.Printf("当前版本输出: %s\n", string(output))
		fmt.Printf(redText+"\n", "要求: JDK 17")
		return
	}
	printSuccess("JDK版本符合要求")

	// 检查 Node.js 版本
	cmd = exec.Command("node", "-v")
	output, err = cmd.CombinedOutput()
	if err != nil {
		printError("检查Node.js失败")
		fmt.Printf("错误: %v\n", err)
		fmt.Println("输出:", string(output))
		return
	}
	nodeVersion := strings.TrimSpace(string(output))
	if !strings.HasPrefix(nodeVersion, "v18") {
		printError("Nodejs版本不正确")
		fmt.Printf("当前版本: %s\n", nodeVersion)
		fmt.Printf(redText+"\n", "要求: Node.js 18.x")
		return
	}
	printSuccess("Nodejs版本符合要求")

	// 检查 RDA 安装
	rdaPath := filepath.Clean("C:\\RDA")

	fi, err := os.Stat(rdaPath)
	if err != nil {
		if os.IsPermission(err) {
			printError("权限不足，无法访问RDA目录")
		} else if os.IsNotExist(err) {
			printError("RDA未安装")
		} else {
			printError("RDA目录检查失败")
		}
		return
	}

	if !fi.IsDir() {
		printError("RDA安装路径不是目录")
		return
	}
	printSuccess("RDA已安装")

	// 检查 RDA 服务状态
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	resp, err := client.Get("https://127.0.0.1:7090/test")
	if err != nil {
		printError("RDA未成功启动")
		fmt.Printf(redText+"\n", fmt.Sprintf("连接错误: %v", err))
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != 500 {
		printError("RDA未成功启动")
		fmt.Printf(redText+"\n", fmt.Sprintf("状态码: %d", resp.StatusCode))
		return
	}
	printSuccess("RDA服务运行正常")
}

func requestAdminPrivileges() error {
	exe, err := os.Executable()
	if err != nil {
		return fmt.Errorf("获取程序路径失败: %v", err)
	}

	verb := "runas"
	exe = strings.ReplaceAll(exe, "/", "\\")

	verbPtr, _ := syscall.UTF16PtrFromString(verb)
	exePtr, _ := syscall.UTF16PtrFromString(exe)

	err = windows.ShellExecute(0, verbPtr, exePtr, nil, nil, windows.SW_SHOW)
	if err != nil {
		return fmt.Errorf("启动管理员权限进程失败: %v", err)
	}

	return nil
}

func init() {
	// 启用 Windows 控制台的 ANSI 支持
	stdout := windows.Handle(os.Stdout.Fd())
	var mode uint32
	windows.GetConsoleMode(stdout, &mode)
	windows.SetConsoleMode(stdout, mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING)
}

func handleLicenseCrack() error {
	// 1. 禁用认证
	if err := togglePgAuth(false); err != nil {
		return fmt.Errorf("禁用认证失败: %v", err)
	}

	// 2. 执行SQL
	connStr := fmt.Sprintf("postgres://%s:%d/%s?sslmode=%s", dbUser, dbPort, dbName, dbSSLMode)
	db, err := sql.Open("postgres", connStr)
	if err != nil {
		return fmt.Errorf("数据库连接失败: %v", err)
	}
	defer db.Close()

	sql := `
	DELETE FROM tb_license;
	INSERT INTO tb_license(id, name, expire_date, trial_status) 
	VALUES(1, 'cracked', 
		ceil(extract(epoch from to_timestamp('2036-01-01', 'YYYY-MM-DD'))*1000), 
		'TRIAL_ING');`

	if _, err := db.Exec(sql); err != nil {
		return fmt.Errorf("SQL执行失败: %v", err)
	}

	// 3. 恢复认证
	if err := togglePgAuth(true); err != nil {
		return fmt.Errorf("恢复认证失败: %v", err)
	}

	return nil
}

type MigratorConfig struct {
	Name        string      `yaml:"migratorName"`
	Code        string      `yaml:"migratorCode"`
	Port        int         `yaml:"migratorPort"`
	ServerHost  string      `yaml:"serverHost"`
	ProjectPath string      `yaml:"migratorProjectPath"`
	DBName      string      `yaml:"dbName"`
	DBPassword  string      `yaml:"dbPassword"`
	Debug       DebugConfig `yaml:"debug,omitempty"`
}

type DebugConfig struct {
	BackendURL   string   `yaml:"backendUrl"`
	FrontendURL  string   `yaml:"frontendUrl"`
	MetaPath     string   `yaml:"metaPath"`
	MetaContent  MetaJson `yaml:"metaContent"`
	DebugEnabled bool     `yaml:"debugEnabled"` // 新增：是否启用调试模式
}

type MetaJson struct {
	Name     string   `json:"name"`
	NameEnUS string   `json:"name_en_US"`
	Version  string   `json:"version"`
	Routers  []Router `json:"routers"`
}

type Router struct {
	Title     string `json:"title"`
	TitleEnUS string `json:"title_en_US"`
	Router    string `json:"router"`
}

const defaultMetaJson = `{
    "name": "migratorName",
    "name_en_US": "migratorName",
    "version": "1.0.0",
    "routers": [
        {
            "title": "Home",
            "title_en_US": "Home",
            "router": "/index"
        }
    ]
}`

func handleMigGen() error {
	config, err := collectMigrationInfo()
	if err != nil {
		return err
	}

	if err := createDatabaseSchema(config); err != nil {
		return fmt.Errorf("数据库创建失败: %v", err)
	}

	// 创建项目目录结构
	if err := generateProjectStructure(config); err != nil {
		return fmt.Errorf("项目生成失败: %v", err)
	}

	// 保存配置文件
	if err := saveConfig(config); err != nil {
		return fmt.Errorf("保存配置失败: %v", err)
	}

	printSuccess(fmt.Sprintf(
		"项目创建成功！\n路径: %s\n数据库信息:\n  名称: %s\n  密码: %s",
		filepath.Join(config.ProjectPath, config.Code),
		config.Code,
		config.DBPassword,
	))
	return nil
}

func selectMigratorConfig() (*MigratorConfig, error) {
	// 获取配置文件目录
	home, err := os.UserHomeDir()
	if err != nil {
		return nil, fmt.Errorf("获取用户目录失败: %v", err)
	}
	configDir := filepath.Join(home, ".rda-migrator")

	fmt.Printf("正在检查配置目录: %s\n", configDir)

	// 确保目录存在
	if err := os.MkdirAll(configDir, 0755); err != nil {
		return nil, fmt.Errorf("创建配置目录失败: %v", err)
	}

	// 递归查找所有配置文件
	configs, err := findConfigFiles(configDir)
	if err != nil {
		return nil, fmt.Errorf("搜索配置文件失败: %v", err)
	}

	if len(configs) == 0 {
		return nil, fmt.Errorf("未找到可用的配置文件，请先使用migen命令生成")
	}

	// 让用户选择配置文件
	fmt.Println("\n可用的配置文件:")
	for i, relPath := range configs {
		configPath := filepath.Join(configDir, relPath)
		var config MigratorConfig
		if data, err := os.ReadFile(configPath); err == nil {
			if err := yaml.Unmarshal(data, &config); err == nil {
				fmt.Printf("[%d] %s (插件名称: %s, 代码: %s)\n", i+1, relPath, config.Name, config.Code)
				continue
			}
		}
		fmt.Printf("[%d] %s\n", i+1, relPath)
	}

	reader := bufio.NewReader(os.Stdin)
	var selected int
	for {
		fmt.Print("\n请选择要调试的配置 (1-", len(configs), "): ")
		input, _ := reader.ReadString('\n')
		num, err := strconv.Atoi(strings.TrimSpace(input))
		if err == nil && num > 0 && num <= len(configs) {
			selected = num - 1
			break
		}
		fmt.Println("无效的选择，请重试")
	}

	// 读取选中的配置文件
	configPath := filepath.Join(configDir, configs[selected])
	data, err := os.ReadFile(configPath)
	if err != nil {
		return nil, fmt.Errorf("读取配置文件失败: %v", err)
	}

	var config MigratorConfig
	if err := yaml.Unmarshal(data, &config); err != nil {
		return nil, fmt.Errorf("解析配置文件失败: %v", err)
	}

	return &config, nil
}

func findConfigFiles(dir string) ([]string, error) {
	var configs []string
	err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if !info.IsDir() && strings.HasSuffix(strings.ToLower(info.Name()), ".yaml") {
			// 尝试读取并验证配置文件
			if data, err := os.ReadFile(path); err == nil {
				var testConfig MigratorConfig
				if err := yaml.Unmarshal(data, &testConfig); err == nil && testConfig.Code != "" {
					// 使用相对路径存储
					relPath, err := filepath.Rel(dir, path)
					if err == nil {
						configs = append(configs, relPath)
						fmt.Printf("找到有效配置文件: %s (插件代码: %s)\n", relPath, testConfig.Code)
					}
				} else {
					fmt.Printf("跳过无效配置文件: %s (错误: %v)\n", path, err)
				}
			}
		}
		return nil
	})
	return configs, err
}

func saveConfig(config *MigratorConfig) error {
	// 确保配置目录存在
	home, err := os.UserHomeDir()
	if err != nil {
		return fmt.Errorf("获取用户目录失败: %v", err)
	}
	configDir := filepath.Join(home, ".rda-migrator")
	if err := os.MkdirAll(configDir, 0755); err != nil {
		return fmt.Errorf("创建配置目录失败: %v", err)
	}

	// 保存到.rda-migrator目录
	configPath := filepath.Join(configDir, config.Code, config.Code+".yaml")
	data, err := yaml.Marshal(config)
	if err != nil {
		return fmt.Errorf("序列化配置失败: %v", err)
	}

	if err := os.WriteFile(configPath, data, 0644); err != nil {
		return fmt.Errorf("写入配置文件失败: %v", err)
	}

	// 验证文件是否已正确保存
	if _, err := os.Stat(configPath); err != nil {
		return fmt.Errorf("配置文件保存后无法访问: %v", err)
	}

	fmt.Printf("配置已保存到: %s\n", configPath)
	return nil
}

func handleMigRun() error {
	fmt.Println("开始执行migrun命令...")

	// 选择配置文件
	config, err := selectMigratorConfig()
	if err != nil {
		return fmt.Errorf("选择配置文件失败: %v", err)
	}

	// 启用调试模式
	config.Debug.DebugEnabled = true
	fmt.Printf("调试信息:\n配置名称: %s\n项目路径: %s\n", config.Name, config.ProjectPath)

	// 收集调试信息
	fmt.Println("\n正在收集调试信息...")
	if err := collectDebugInfo(config); err != nil {
		return fmt.Errorf("收集调试信息失败: %v", err)
	}

	// 保存更新后的配置
	if err := saveConfig(config); err != nil {
		return fmt.Errorf("保存调试信息失败: %v", err)
	}

	fmt.Printf("调试信息收集完成:\n- 后端URL: %s\n- 前端URL: %s\n- Meta文件: %s\n",
		config.Debug.BackendURL,
		config.Debug.FrontendURL,
		config.Debug.MetaPath)

	// 确保meta.json存在
	fmt.Println("\n正在处理meta.json...")
	if err := ensureMetaJson(config); err != nil {
		return fmt.Errorf("处理meta.json失败: %v", err)
	}

	// 根据config中的信息使用pgsqlrda账号连接数据库插入migrator信息
	fmt.Println("\n正在准备migrator信息...")
	if err := prepareMigratorInfo(config); err != nil {
		return fmt.Errorf("准备migrator信息失败: %v", err)
	}

	// 生成或加载SSL证书
	fmt.Println("\n正在准备SSL证书...")
	cert, err := ensureSSLCert()
	if err != nil {
		return fmt.Errorf("准备SSL证书失败: %v", err)
	}
	fmt.Println("SSL证书准备完成")

	// 2. 获取随机端口
	debugPort, err := getRandomPort()
	if err != nil {
		return fmt.Errorf("获取随机端口失败: %v", err)
	}
	// 启动调试服务器
	fmt.Println("\n正在启动调试服务器...")

	// 创建一个channel用于等待服务器启动
	errChan := make(chan error, 1)

	// 在goroutine中启动服务器
	go func() {
		err := startDebugServer(config, cert, debugPort)
		if err != nil {
			errChan <- fmt.Errorf("服务器启动失败: %v", err)
		}
	}()

	// 等待几秒钟，看服务器是否正常启动
	select {
	case err := <-errChan:
		return err
	case <-time.After(2 * time.Second):
		fmt.Println("调试服务器启动成功！")
		fmt.Println("\n请在浏览器中访问以下地址:")
		fmt.Printf("https://localhost:%d\n", debugPort)
		fmt.Println("\n按Ctrl+C停止服务器")
	}

	// 阻塞主线程，等待用户手动终止
	select {}
}

func prepareMigratorInfo(config *MigratorConfig) error {
	// 禁用pgsql的权限认证
	if err := togglePgAuth(false); err != nil {
		return fmt.Errorf("禁用权限认证失败: %v", err)
	}

	migratorRecordId := "1001"
	// 利用pgsqlrda账号连接数据库先删除migratorRecordId的数据
	db, err := connectToDatabase(dbUser, "")
	if err != nil {
		return err
	}
	defer db.Close()

	// 删除migrator记录
	_, err = db.Exec("DELETE FROM tb_migrator WHERE id = $1", migratorRecordId)
	if err != nil {
		return fmt.Errorf("删除migrator记录失败: %v", err)
	}

	// 创建migrator记录
	query := `
        INSERT INTO tb_migrator (
            id, code, platform, name, name_en, version, description, description_en,
            install_status, runtime_status, download_file_name, installer_validation_result,
            installer_version, service_host, service_port, runtime_error, db_schema,
            db_pass, custom_config
        ) VALUES (
            $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15,
            $16, $17, $18, $19
        )`

	_, err = db.Exec(query,
		migratorRecordId,   // id
		config.Code,        // code
		"windows",          // platform
		config.Name,        // name
		config.Name,        // name_en
		"1.0.0",            // version
		config.Name,        // description
		config.Name,        // description_en
		"INSTALL_FINISHED", // install_status
		"RUNNING",          // runtime_status
		"",                 // download_file_name
		"[]",               // installer_validation_result
		"1.0.0",            // installer_version
		config.ServerHost,  // service_host
		config.Port,        // service_port
		"",                 // runtime_error
		config.Code,        // db_schema
		config.DBPassword,  // db_pass
		"{}",               // custom_config
	)

	if err != nil {
		return fmt.Errorf("创建migrator记录失败: %v", err)
	}

	// 重启pgsql
	defer togglePgAuth(true)
	return nil
}

func collectDebugInfo(config *MigratorConfig) error {
	reader := bufio.NewReader(os.Stdin)

	// 收集后端地址
	config.Debug.BackendURL = promptInput(reader,
		fmt.Sprintf("请输入插件后端地址（默认：%s）: ", getDefaultOrValue(config.Debug.BackendURL, "http://127.0.0.1:8844")),
		getDefaultOrValue(config.Debug.BackendURL, "http://127.0.0.1:8844"),
		validateURL,
	)

	// 收集前端地址
	config.Debug.FrontendURL = promptInput(reader,
		fmt.Sprintf("请输入插件前端地址（默认：%s）: ", getDefaultOrValue(config.Debug.FrontendURL, "http://127.0.0.1:4200")),
		getDefaultOrValue(config.Debug.FrontendURL, "http://127.0.0.1:4200"),
		validateURL,
	)

	// 收集meta.json路径
	defaultMetaPath := filepath.Join(config.ProjectPath, config.Code, "meta.json")
	if config.Debug.MetaPath != "" {
		defaultMetaPath = config.Debug.MetaPath
	}
	config.Debug.MetaPath = promptInput(reader,
		fmt.Sprintf("请输入meta.json路径（默认：%s）: ", getDefaultOrValue(config.Debug.MetaPath, defaultMetaPath)),
		defaultMetaPath,
		nil,
	)

	// 确保meta.json存在并且格式正确
	if err := ensureMetaJson(config); err != nil {
		return err
	}

	return nil
}

func validateURL(input string) error {
	if _, err := url.Parse(input); err != nil {
		return fmt.Errorf("无效的URL格式: %v", err)
	}
	return nil
}

func getDefaultOrValue(value, defaultValue string) string {
	if value != "" {
		return value
	}
	return defaultValue
}

func ensureMetaJson(config *MigratorConfig) error {
	fmt.Printf("正在处理meta.json...\n")
	fmt.Printf("meta.json路径: %s\n", config.Debug.MetaPath)

	// 确保meta.json所在目录存在
	metaDir := filepath.Dir(config.Debug.MetaPath)
	if err := os.MkdirAll(metaDir, 0755); err != nil {
		return fmt.Errorf("创建meta.json目录失败: %v", err)
	}

	// 读取或创建meta.json
	var metaContent []byte
	var err error

	metaContent, err = os.ReadFile(config.Debug.MetaPath)
	if err != nil {
		if os.IsNotExist(err) {
			fmt.Println("meta.json不存在，将创建默认文件")
			// 替换默认内容中的占位符
			defaultContent := strings.ReplaceAll(defaultMetaJson, "migratorName", config.Name)
			metaContent = []byte(defaultContent)

			// 创建文件
			if err := os.WriteFile(config.Debug.MetaPath, metaContent, 0644); err != nil {
				return fmt.Errorf("创建meta.json失败: %v", err)
			}
			fmt.Printf("已创建默认的meta.json文件: %s\n", config.Debug.MetaPath)
		} else {
			return fmt.Errorf("读取meta.json失败: %v", err)
		}
	} else {
		fmt.Println("已找到现有的meta.json文件")
	}

	// 验证JSON格式
	var meta MetaJson
	if err := json.Unmarshal(metaContent, &meta); err != nil {
		fmt.Printf("meta.json内容:\n%s\n", string(metaContent))
		return fmt.Errorf("meta.json格式错误: %v", err)
	}

	// 验证必要字段
	if meta.Name == "" {
		return fmt.Errorf("meta.json缺少必要字段: name")
	}
	if meta.NameEnUS == "" {
		return fmt.Errorf("meta.json缺少必要字段: name_en_US")
	}
	if meta.Version == "" {
		return fmt.Errorf("meta.json缺少必要字段: version")
	}
	if len(meta.Routers) == 0 {
		return fmt.Errorf("meta.json缺少必要字段: routers")
	}

	// 保存到配置中
	config.Debug.MetaContent = meta
	fmt.Println("meta.json验证通过")
	return nil
}

func startDebugServer(config *MigratorConfig, cert tls.Certificate, debugPort int) error {
	// 1. 生成或加载证书
	certDir := filepath.Join(config.ProjectPath, config.Code, "certs")
	certFile := filepath.Join(certDir, "server.crt")
	keyFile := filepath.Join(certDir, "server.key")

	if err := os.MkdirAll(certDir, 0755); err != nil {
		return fmt.Errorf("创建证书目录失败: %v", err)
	}

	if !fileExists(certFile) || !fileExists(keyFile) {
		if err := generateCertificate(certFile, keyFile); err != nil {
			return fmt.Errorf("生成证书失败: %v", err)
		}
	}

	// 3. 创建HTTPS服务器
	server := &http.Server{
		Addr:    fmt.Sprintf(":%d", debugPort),
		Handler: createDebugHandler(config),
		TLSConfig: &tls.Config{
			MinVersion:   tls.VersionTLS12,
			Certificates: []tls.Certificate{cert},
		},
	}

	// 4. 启动服务器
	fmt.Printf("调试服务器启动在 https://127.0.0.1:%d\n", debugPort)
	fmt.Printf("插件代码: %s\n", config.Code)
	fmt.Printf("后端地址: %s\n", config.Debug.BackendURL)
	fmt.Printf("前端地址: %s\n", config.Debug.FrontendURL)

	return server.ListenAndServeTLS("", "")
}

func createDebugHandler(config *MigratorConfig) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// 使用自定义ResponseWriter来捕获状态码
		rw := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}

		// 构建apiKey
		apiKey := fmt.Sprintf("%s %s", r.Method, r.URL.Path)

		// 1. 处理控制台文件夹请求
		if apiKey == "GET /v2/rda/migrators/console-folders" {
			rw.Header().Set("Content-Type", "application/json")
			json.NewEncoder(rw).Encode([]string{config.Code})
			logRequest(r, "直接响应", "-", "-", rw.statusCode)
			return
		}

		// 2. 处理meta.json请求
		metaPath := fmt.Sprintf("/extensions/%s/meta.json", config.Code)
		if apiKey == "GET "+metaPath {
			rw.Header().Set("Content-Type", "application/json")
			json.NewEncoder(rw).Encode(config.Debug.MetaContent)
			logRequest(r, "直接响应", "-", "-", rw.statusCode)
			return
		}

		// 3. 判断是否需要转发到前端或后端
		if shouldForwardToPlugin(r, config.Code) {
			handlePluginForward(rw, r, config)
			return
		}
		fmt.Println("未匹配到插件请求")

		// 4. 其他请求转发到RDA
		forwardToRDA(rw, r)
	})
}

func shouldForwardToPlugin(r *http.Request, code string) bool {
	apiKey := fmt.Sprintf("%s %s", r.Method, r.URL.Path)
	referer := r.Header.Get("Referer")

	// 检查是否满足任一转发条件
	return strings.HasSuffix(referer, fmt.Sprintf("/extensions/%s/index.html", code)) ||
		apiKey == fmt.Sprintf("HEAD /extensions/%s/index.html", code) ||
		apiKey == fmt.Sprintf("GET /extensions/%s/index.html", code) ||
		strings.HasPrefix(apiKey, "GET /src/") ||
		strings.HasPrefix(apiKey, "GET /@") ||
		strings.HasPrefix(apiKey, "GET /node_modules/") ||
		strings.HasPrefix(apiKey, "GET /assets/") ||
		strings.HasPrefix(r.Header.Get("Upgrade"), "websocket")
}

func handlePluginForward(w http.ResponseWriter, r *http.Request, config *MigratorConfig) {
	rw, ok := w.(*responseWriter)
	if !ok {
		rw = &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}
	}

	// 2.6.1 获取apiKey
	apiKey := fmt.Sprintf("%s %s", r.Method, r.URL.Path)

	// 2.6.2 处理获取console-folders请求
	if apiKey == "GET /v2/rda/migrators/console-folders" {
		response := []string{config.Code}
		jsonResponse, _ := json.Marshal(response)
		rw.Header().Set("Content-Type", "application/json")
		rw.Write(jsonResponse)
		logRequest(r, "直接响应", "-", "-", rw.statusCode)
		return
	}

	// 2.6.3 处理meta.json请求
	expectedMetaPath := fmt.Sprintf("/extensions/%s/meta.json", config.Code)
	if apiKey == fmt.Sprintf("GET %s", expectedMetaPath) {
		rw.Header().Set("Content-Type", "application/json")
		metaJSON, err := os.ReadFile(config.Debug.MetaPath)
		if err != nil {
			http.Error(rw, "Failed to read meta.json", http.StatusInternalServerError)
			logRequest(r, "直接响应", "-", "-", http.StatusInternalServerError)
			return
		}
		rw.Write(metaJSON)
		logRequest(r, "直接响应1", "-", "-", rw.statusCode)
		return
	}

	// 2.6.4 判断是否应该转发给前端插件
	isPluginRequest := false

	// 2.6.4.1 检查referer
	referer := r.Header.Get("Referer")
	if referer != "" && strings.HasSuffix(referer, fmt.Sprintf("/extensions/%s/index.html", config.Code)) {
		isPluginRequest = true
	}

	// 2.6.4.2 和 2.6.4.3 检查index.html请求
	expectedIndexPath := fmt.Sprintf("/extensions/%s/index.html", config.Code)
	if apiKey == fmt.Sprintf("HEAD %s", expectedIndexPath) ||
		apiKey == fmt.Sprintf("GET %s", expectedIndexPath) {
		isPluginRequest = true
	}

	// 2.6.4.4 检查其他静态资源和WebSocket请求
	if strings.HasSuffix(apiKey, "/common.js") ||
		strings.HasSuffix(apiKey, "/src_app_pages_servers_servers_module_ts.js") ||
		strings.HasPrefix(apiKey, "GET /src/") ||
		strings.HasPrefix(apiKey, "GET /@") ||
		strings.HasPrefix(apiKey, "GET /node_modules/") ||
		strings.HasPrefix(apiKey, "GET /assets/") ||
		strings.HasPrefix(r.Header.Get("Upgrade"), "websocket") {
		isPluginRequest = true
	}

	if isPluginRequest {
		// 处理WebSocket请求
		if strings.HasPrefix(r.Header.Get("Upgrade"), "websocket") {
			frontendUrl, err := url.Parse(config.Debug.FrontendURL)
			if err != nil {
				http.Error(rw, fmt.Sprintf("解析前端URL失败: %v", err), http.StatusInternalServerError)
				logRequest(r, "To-Plugin-Front-WS", config.Debug.FrontendURL, r.URL.Path, http.StatusInternalServerError)
				return
			}

			// 将http/https替换为ws/wss
			wsURL := *frontendUrl
			if wsURL.Scheme == "https" {
				wsURL.Scheme = "ws"
			} else {
				wsURL.Scheme = "ws"
			}

			// 设置目标URL
			r.URL.Host = wsURL.Host
			r.URL.Scheme = wsURL.Scheme
			r.Host = wsURL.Host

			// 创建到目标WebSocket服务器的连接
			dialer := websocket.Dialer{
				TLSClientConfig: &tls.Config{
					InsecureSkipVerify: true,
				},
				EnableCompression: true,
			}

			// 构建请求头
			requestHeader := http.Header{}
			for k, v := range r.Header {
				requestHeader[k] = v
			}

			// 连接到目标WebSocket服务器
			targetConn, resp, err := dialer.Dial(wsURL.String()+r.URL.Path, requestHeader)
			if err != nil {
				statusCode := http.StatusInternalServerError
				if resp != nil {
					statusCode = resp.StatusCode
				}
				http.Error(rw, fmt.Sprintf("连接WebSocket服务器失败: %v", err), statusCode)
				logRequest(r, "To-Plugin-Front-WS", wsURL.Host, r.URL.Path, statusCode)
				return
			}
			defer targetConn.Close()

			// 升级客户端连接为WebSocket
			upgrader := websocket.Upgrader{
				CheckOrigin: func(r *http.Request) bool {
					return true
				},
			}
			clientConn, err := upgrader.Upgrade(rw, r, nil)
			if err != nil {
				http.Error(rw, fmt.Sprintf("升级WebSocket连接失败: %v", err), http.StatusInternalServerError)
				logRequest(r, "To-Plugin-Front-WS", wsURL.Host, r.URL.Path, http.StatusInternalServerError)
				return
			}
			defer clientConn.Close()

			// 记录WebSocket连接成功
			logRequest(r, "To-Plugin-Front-WS", wsURL.Host, r.URL.Path, http.StatusSwitchingProtocols)

			// 创建双向通道
			errChan := make(chan error, 2)

			// 从客户端转发到目标服务器
			go func() {
				for {
					messageType, message, err := clientConn.ReadMessage()
					if err != nil {
						errChan <- err
						return
					}
					if err := targetConn.WriteMessage(messageType, message); err != nil {
						errChan <- err
						return
					}
				}
			}()

			// 从目标服务器转发到客户端
			go func() {
				for {
					messageType, message, err := targetConn.ReadMessage()
					if err != nil {
						errChan <- err
						return
					}
					if err := clientConn.WriteMessage(messageType, message); err != nil {
						errChan <- err
						return
					}
				}
			}()

			// 等待任一方连接关闭
			<-errChan
			return
		}

		// 2.6.5 处理插件请求
		if apiKey == "GET "+expectedIndexPath {
			resp, err := http.Get(config.Debug.FrontendURL + "/index.html")
			if err != nil {
				http.Error(rw, fmt.Sprintf("获取前端内容失败: %v", err), http.StatusInternalServerError)
				logRequest(r, "To-Plugin-Front", config.Debug.FrontendURL, "/index.html", http.StatusInternalServerError)
				return
			}
			defer resp.Body.Close()

			// 复制响应头
			for key, values := range resp.Header {
				for _, value := range values {
					rw.Header().Add(key, value)
				}
			}
			// 设置默认Content-Type
			if rw.Header().Get("Content-Type") == "" {
				rw.Header().Set("Content-Type", "text/html; charset=utf-8")
			}

			// 复制响应体
			io.Copy(rw, resp.Body)
			logRequest(r, "Direct-Get-Index", config.Debug.FrontendURL, "/index.html", resp.StatusCode)
			return
		}

		// 2.6.5.2 处理HEAD index.html
		if apiKey == fmt.Sprintf("HEAD %s", expectedIndexPath) {
			rw.WriteHeader(http.StatusOK)
			logRequest(r, "Direct-Head-Index", config.Debug.FrontendURL, "/index.html", http.StatusOK)
			return
		}

		// 2.6.5.3 其余请求转发到插件前端
		frontendUrl, err := url.Parse(config.Debug.FrontendURL)
		if err != nil {
			http.Error(rw, fmt.Sprintf("解析前端URL失败: %v", err), http.StatusInternalServerError)
			logRequest(r, "To-Plugin-Front", config.Debug.FrontendURL, r.URL.Path, http.StatusInternalServerError)
			return
		}

		proxy := httputil.NewSingleHostReverseProxy(frontendUrl)
		r.URL.Host = frontendUrl.Host
		r.URL.Scheme = frontendUrl.Scheme
		r.Host = frontendUrl.Host

		// 包装ServeHTTP以记录响应状态码
		originalDirector := proxy.Director
		proxy.Director = func(req *http.Request) {
			originalDirector(req)
			logRequest(r, "To-Plugin-Front", frontendUrl.Host, req.URL.Path, rw.statusCode)
		}

		proxy.ServeHTTP(rw, r)
		return
	}

	// 2.6.6 其他请求转发给RDA
	rdaURL, _ := url.Parse("https://127.0.0.1:7090")
	proxy := httputil.NewSingleHostReverseProxy(rdaURL)

	// 配置TLS
	proxy.Transport = &http.Transport{
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
		},
	}

	r.URL.Host = rdaURL.Host
	r.URL.Scheme = rdaURL.Scheme
	r.Host = rdaURL.Host

	// 包装ServeHTTP以记录响应状态码
	originalDirector := proxy.Director
	proxy.Director = func(req *http.Request) {
		originalDirector(req)
		logRequest(r, "To-RDA", rdaURL.Host, req.URL.Path, rw.statusCode)
	}

	proxy.ServeHTTP(rw, r)
}

func forwardToRDA(w http.ResponseWriter, r *http.Request) {
	rw, ok := w.(*responseWriter)
	if !ok {
		rw = &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}
	}
	forwardRequest(rw, r, "https://127.0.0.1:7090")
}

func forwardRequest(w http.ResponseWriter, r *http.Request, target string) {
	rw, ok := w.(*responseWriter)
	if !ok {
		rw = &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}
	}

	targetURL, err := url.Parse(target)
	if err != nil {
		http.Error(rw, "Invalid target URL", http.StatusInternalServerError)
		logRequest(r, "To-RDA", target, r.URL.Path, http.StatusInternalServerError)
		return
	}

	proxy := httputil.NewSingleHostReverseProxy(targetURL)
	proxy.Transport = &http.Transport{
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
		},
	}

	r.URL.Host = targetURL.Host
	r.URL.Scheme = targetURL.Scheme
	r.Host = targetURL.Host

	// 包装ServeHTTP以记录响应状态码
	originalDirector := proxy.Director
	proxy.Director = func(req *http.Request) {
		originalDirector(req)
		logRequest(r, "To-RDA", targetURL.Host, req.URL.Path, rw.statusCode)
	}

	proxy.ServeHTTP(rw, r)
}

func generateCertificate(certFile, keyFile string) error {
	// 生成私钥
	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		return err
	}

	// 创建证书模板
	template := x509.Certificate{
		SerialNumber: big.NewInt(1),
		Subject: pkix.Name{
			Organization: []string{"RDA Debug"},
		},
		NotBefore: time.Now(),
		NotAfter:  time.Now().AddDate(10, 0, 0),

		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
		BasicConstraintsValid: true,

		DNSNames:    []string{"localhost"},
		IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
	}

	// 创建证书
	derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey)
	if err != nil {
		return err
	}

	// 保存证书
	certOut, err := os.Create(certFile)
	if err != nil {
		return err
	}
	defer certOut.Close()

	if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
		return err
	}

	// 保存私钥
	keyOut, err := os.Create(keyFile)
	if err != nil {
		return err
	}
	defer keyOut.Close()

	if err := pem.Encode(keyOut, &pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
	}); err != nil {
		return err
	}

	return nil
}

func getRandomPort() (int, error) {
	listener, err := net.Listen("tcp", ":0")
	if err != nil {
		return 0, err
	}
	defer listener.Close()

	return listener.Addr().(*net.TCPAddr).Port, nil
}

func fileExists(path string) bool {
	_, err := os.Stat(path)
	return !os.IsNotExist(err)
}

func collectMigrationInfo() (*MigratorConfig, error) {
	config := &MigratorConfig{}
	reader := bufio.NewReader(os.Stdin)

	// 收集迁移器名称
	config.Name = promptInput(reader,
		fmt.Sprintf("请输入迁移器名称（默认：%s）: ", generateChineseName()),
		generateChineseName(),
		func(input string) error {
			if input == "" {
				return fmt.Errorf("名称不能为空")
			}
			return nil
		},
	)

	// 收集迁移器代码
	config.Code = promptInput(reader,
		fmt.Sprintf("请输入迁移器代码（默认：%s）: ", generateRandomCode()),
		generateRandomCode(),
		func(input string) error {
			if match, _ := regexp.MatchString(`^[a-z]{3,8}$`, input); !match {
				return fmt.Errorf("代码必须为3-8位小写字母")
			}
			return nil
		},
	)

	// 收集迁移器ServiceHost
	config.ServerHost = promptInput(reader,
		fmt.Sprintf("请输入迁移器ServerHost（默认: %s）: ", "http://127.0.0.1"),
		"http://127.0.0.1",
		func(input string) error {
			if match, _ := regexp.MatchString(`^https?:\/\/127\.0\.0\.1$`, input); !match {
				return fmt.Errorf("ServerHost必须为http://127.0.0.1或者https://127.0.0.1")
			}
			return nil
		},
	)

	// 收集端口号
	portStr := promptInput(reader,
		fmt.Sprintf("请输入服务端口（默认: %d）: ", generateRandomPort()),
		strconv.Itoa(generateRandomPort()),
		func(input string) error {
			port, err := strconv.Atoi(input)
			if err != nil || port < 1000 || port > 10000 {
				return fmt.Errorf("端口必须为1000-10000之间的数字")
			}
			return nil
		},
	)
	config.Port, _ = strconv.Atoi(portStr)

	// 收集项目路径
	config.ProjectPath = promptInput(reader,
		fmt.Sprintf("请输入项目路径（默认：%s）: ", getDefaultProjectPath()),
		getDefaultProjectPath(),
		func(input string) error {
			if err := os.MkdirAll(input, 0755); err != nil {
				return fmt.Errorf("目录创建失败: %v", err)
			}
			return nil
		},
	)

	// 生成数据库信息
	config.DBName = config.Code
	config.DBPassword = generateRandomPassword(8)

	// 确认信息
	if !confirmConfig(reader, config) {
		return collectMigrationInfo() // 重新收集
	}

	return config, nil
}

func createDatabaseSchema(config *MigratorConfig) error {
	// 禁用认证
	if err := togglePgAuth(false); err != nil {
		return fmt.Errorf("禁用认证失败: %v", err)
	}
	defer togglePgAuth(true)

	// 创建数据库连接
	db, err := connectToDatabase(dbUser, "")
	if err != nil {
		return err
	}
	defer db.Close()

	// 使用事务执行
	tx, err := db.Begin()
	if err != nil {
		return fmt.Errorf("事务启动失败: %v", err)
	}
	defer tx.Rollback()

	// 执行创建语句
	queries := []string{
		// 创建用户
		fmt.Sprintf("DROP USER IF EXISTS %s", config.Code),
		fmt.Sprintf("CREATE USER %s WITH PASSWORD '%s'", config.Code, config.DBPassword),

		// 创建并配置schema
		fmt.Sprintf("DROP SCHEMA IF EXISTS %s CASCADE", config.Code),
		fmt.Sprintf("CREATE SCHEMA %s", config.Code),
		fmt.Sprintf("ALTER SCHEMA %s OWNER TO %s", config.Code, config.Code),

		// 设置权限
		fmt.Sprintf("GRANT ALL ON SCHEMA %s TO %s", config.Code, config.Code),
		fmt.Sprintf("ALTER USER %s SET search_path TO %s", config.Code, config.Code),

		// 创建基础表（如果需要）
		fmt.Sprintf("SET search_path TO %s", config.Code),
	}

	for _, query := range queries {
		if _, err := tx.Exec(query); err != nil {
			return fmt.Errorf("执行SQL失败: %v\nSQL: %s", err, query)
		}
	}

	return tx.Commit()
}

func generateProjectStructure(ctx *MigratorConfig) error {
	targetDir := filepath.Join(ctx.ProjectPath, ctx.Code, ctx.Code)

	// 创建项目目录
	if err := os.MkdirAll(targetDir, 0755); err != nil {
		return fmt.Errorf("创建目录失败: %v", err)
	}

	// 创建目标目录
	destDir := filepath.Join(targetDir)
	if err := os.MkdirAll(destDir, 0755); err != nil {
		log.Fatal(err)
	}

	// 递归解压嵌入文件
	if err := fs.WalkDir(embeddedTemplates, "templates", func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}

		// 构建目标路径
		relPath, _ := filepath.Rel("templates", path)
		targetPath := filepath.Join(destDir, relPath)

		if d.IsDir() {
			return os.MkdirAll(targetPath, 0755)
		}

		// 写入文件
		data, err := fs.ReadFile(embeddedTemplates, path)
		if err != nil {
			return err
		}
		renderedData, err := renderTemplate(data, *ctx)
		if err != nil {
			return fmt.Errorf("failed to render %s: %w", path, err)
		} else {
			fmt.Printf("渲染 %s 成功\n", targetPath)
		}
		return os.WriteFile(targetPath, renderedData, 0644)
	}); err != nil {
		log.Fatal(err)
	}
	return nil
}

// 新增模板解析函数
func renderTemplate(content []byte, ctx MigratorConfig) ([]byte, error) {
	tmpl, err := template.New("").Parse(string(content))
	if err != nil {
		return nil, fmt.Errorf("template parse error: %w", err)
	}

	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, ctx); err != nil {
		return nil, fmt.Errorf("template execute error: %w", err)
	}
	return buf.Bytes(), nil
}

func generateChineseName() string {
	names := []string{"数据迁移器", "智能转换器", "云端同步器", "企业适配器"}
	n, _ := rand.Int(rand.Reader, big.NewInt(int64(len(names))))
	return names[n.Int64()]
}

func generateRandomCode() string {
	const letters = "abcdefghijklmnopqrstuvwxyz"
	length, _ := rand.Int(rand.Reader, big.NewInt(6)) // 生成3-8位
	n := int(length.Int64()) + 3                      // 确保最少3位

	b := make([]byte, n)
	for i := range b {
		idx, _ := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
		b[i] = letters[idx.Int64()]
	}
	return string(b)
}

func generateRandomPort() int {
	n, _ := rand.Int(rand.Reader, big.NewInt(1000))
	return 9000 + int(n.Int64())
}

func getDefaultProjectPath() string {
	home, _ := os.UserHomeDir()
	return filepath.Join(home, ".rda-migrator")
}

func promptInput(reader *bufio.Reader, prompt, defaultValue string, validator func(string) error) string {
	for {
		fmt.Print(prompt)
		input, _ := reader.ReadString('\n')
		input = strings.TrimSpace(input)

		if input == "" {
			return defaultValue
		}

		// 如果没有提供验证器，直接返回输入值
		if validator == nil {
			return input
		}

		// 验证输入
		if err := validator(input); err != nil {
			fmt.Printf("输入无效: %v\n", err)
			continue
		}

		return input
	}
}

func confirmConfig(reader *bufio.Reader, config *MigratorConfig) bool {
	fmt.Printf(`
=== 配置预览 ===
名称: %s
代码: %s
端口: %d
路径: %s
数据库: %s
密码: %s
================
确认生成？(Y/n) `,
		config.Name, config.Code, config.Port,
		filepath.Join(config.ProjectPath, config.Code),
		config.DBName, config.DBPassword)

	input, _ := reader.ReadString('\n')
	input = strings.ToLower(strings.TrimSpace(input))
	return input == "y" || input == "" // 只有输入Y或直接回车才继续
}

func generateRandomPassword(length int) string {
	const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	b := make([]byte, length)
	for i := range b {
		n, _ := rand.Int(rand.Reader, big.NewInt(int64(len(chars))))
		b[i] = chars[n.Int64()]
	}
	return string(b)
}

func togglePgAuth(enable bool) error {
	confPath := filepath.Clean("C:/RDA/tools/pgsql/data/pg_hba.conf")
	backupPath := confPath + ".bak"

	// 备份原文件
	if err := os.Rename(confPath, backupPath); err != nil {
		return err
	}

	// 生成新配置
	var newConf string
	if enable {
		newConf = `# Original security settings
host all all 127.0.0.1/32 md5`
	} else {
		newConf = `# Disabled security for license crack
host all all 127.0.0.1/32 trust`
	}

	if err := os.WriteFile(confPath, []byte(newConf), 0600); err != nil {
		return err
	}

	// 重新加载配置
	if err := exec.Command("net", "stop", "RDA_PostgreSQL").Run(); err != nil {
		return fmt.Errorf("停止服务失败: %v", err)
	}
	if err := exec.Command("net", "start", "RDA_PostgreSQL").Run(); err != nil {
		return fmt.Errorf("启动服务失败: %v", err)
	}

	return nil
}

func ensureSSLCert() (tls.Certificate, error) {
	home, err := os.UserHomeDir()
	if err != nil {
		return tls.Certificate{}, fmt.Errorf("获取用户目录失败: %v", err)
	}
	certDir := filepath.Join(home, ".rda-migrator", "certs")
	if err := os.MkdirAll(certDir, 0755); err != nil {
		return tls.Certificate{}, fmt.Errorf("创建证书目录失败: %v", err)
	}

	certFile := filepath.Join(certDir, "server.crt")
	keyFile := filepath.Join(certDir, "server.key")

	// 检查证书是否存在
	if _, err := os.Stat(certFile); err == nil {
		if _, err := os.Stat(keyFile); err == nil {
			// 加载现有证书
			cert, err := tls.LoadX509KeyPair(certFile, keyFile)
			if err == nil {
				fmt.Println("使用现有SSL证书")
				return cert, nil
			}
		}
	}

	// 生成新证书
	fmt.Println("正在生成新的SSL证书...")
	priv, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		return tls.Certificate{}, fmt.Errorf("生成私钥失败: %v", err)
	}

	template := x509.Certificate{
		SerialNumber: big.NewInt(1),
		Subject: pkix.Name{
			Organization: []string{"RDA Debug Server"},
		},
		NotBefore:             time.Now(),
		NotAfter:              time.Now().AddDate(10, 0, 0),
		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
		BasicConstraintsValid: true,
		DNSNames:              []string{"localhost"},
		IPAddresses:           []net.IP{net.ParseIP("127.0.0.1")},
	}

	derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
	if err != nil {
		return tls.Certificate{}, fmt.Errorf("生成证书失败: %v", err)
	}

	// 保存证书
	certOut, err := os.Create(certFile)
	if err != nil {
		return tls.Certificate{}, fmt.Errorf("创建证书文件失败: %v", err)
	}
	if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
		certOut.Close()
		return tls.Certificate{}, fmt.Errorf("写入证书失败: %v", err)
	}
	certOut.Close()

	// 保存私钥
	keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
	if err != nil {
		return tls.Certificate{}, fmt.Errorf("创建私钥文件失败: %v", err)
	}
	privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
	if err != nil {
		keyOut.Close()
		return tls.Certificate{}, fmt.Errorf("序列化私钥失败: %v", err)
	}
	if err := pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil {
		keyOut.Close()
		return tls.Certificate{}, fmt.Errorf("写入私钥失败: %v", err)
	}
	keyOut.Close()

	fmt.Println("SSL证书生成完成")
	return tls.LoadX509KeyPair(certFile, keyFile)
}

type responseWriter struct {
	http.ResponseWriter
	statusCode int
}

func (rw *responseWriter) WriteHeader(code int) {
	rw.statusCode = code
	rw.ResponseWriter.WriteHeader(code)
}

func logRequest(r *http.Request, forwardType string, targetHost string, targetURI string, statusCode int) {
	timestamp := time.Now().Format("2006-01-02 15:04:05")
	fmt.Printf("[%s] [%s %s] %s, targetHost: %s, targetUri: %s, targetResponseCode: %d\n",
		timestamp, r.Method, r.URL.Path, forwardType, targetHost, targetURI, statusCode)
}

func connectToDatabase(username, password string) (*sql.DB, error) {
	connStr := fmt.Sprintf("postgres://%s:%s@%s:%d/%s?sslmode=%s",
		username, password, dbHost, dbPort, dbName, dbSSLMode)

	db, err := sql.Open("postgres", connStr)
	if err != nil {
		return nil, fmt.Errorf("数据库连接失败: %v", err)
	}

	// Test the connection
	if err = db.Ping(); err != nil {
		db.Close()
		return nil, fmt.Errorf("数据库连接测试失败: %v", err)
	}

	return db, nil
}

func main() {
	admin, err := isAdmin()
	if err != nil {
		fmt.Printf("Error checking admin privileges: %v\n", err)
		os.Exit(1)
	}

	if !admin {
		fmt.Println("正在请求管理员权限...")
		if err := requestAdminPrivileges(); err != nil {
			fmt.Printf("Error requesting admin privileges: %v\n", err)
			fmt.Println("请右键点击程序并选择'以管理员身份运行'")
			fmt.Println("\nPress Enter to exit...")
			fmt.Scanln()
			os.Exit(1)
		}
		os.Exit(0)
	}

	printWelcome()

	p := prompt.New(
		executor,
		completer,
		prompt.OptionTitle("RDA Terminal"),
		prompt.OptionPrefix(">>> "),
		prompt.OptionInputTextColor(prompt.Yellow),
		prompt.OptionSuggestionBGColor(prompt.DarkGray),
		prompt.OptionSelectedSuggestionBGColor(prompt.Blue),
		prompt.OptionSelectedSuggestionTextColor(prompt.White),
		prompt.OptionDescriptionBGColor(prompt.DarkGray),
		prompt.OptionSelectedDescriptionBGColor(prompt.Blue),
		prompt.OptionCompletionOnDown(),
	)
	p.Run()
}
